import React, {RefObject} from "react"
import {Input} from 'antd'
import {VJsonComponent} from "../../factory"
import _ from 'lodash'
import {FormItemBaseProp, FormItemBaseState, VJsonFormItemBase} from "./VJsonFormItemBase"
import * as Extend from "../../extend"
import {WidgetOption} from "../widget"
import {CloseOutlined} from '@ant-design/icons'
import {apply, YvanEventDispatch} from "../../utils/helper"
import {toJS, transaction} from "mobx";

const {Search: AntdSearch} = Input;

export interface SearchVJsonProp extends FormItemBaseProp<Search> {
    addonAfter?: string | React.ReactNode
    placeholder?: string
    defaultValue?: string
    disabled?: boolean
    maxLength?: number
    prefix?: string | React.ReactNode
    size?: 'large' | 'middle' | 'small'
    allowClear?: boolean
    bordered?: boolean
    widget: WidgetOption<any, any>
    // 允许修改search 出来的值
    allowModify?: boolean
}

export interface SearchState extends FormItemBaseState<Search> {
    value: string
}

@VJsonComponent({
    view: 'search'
})
export default class Search extends VJsonFormItemBase<Search, SearchVJsonProp, SearchState> {
    static defaultProps = {
        ...VJsonFormItemBase.defaultProps,
        placeholder: '回车键搜索',
        allowClear: true,
        allowModify: false
    }

    keepTempValue: boolean = false
    realCtl: RefObject<Input> = React.createRef()

    constructor(props: any) {
        super(props, Search.defaultProps);
    }

    clearClick() {
        if (typeof this.props.vjson.widget.onClear === 'function') {
            YvanEventDispatch(this.props.vjson.widget.onClear, this)

        } else if (_.isPlainObject(this.props.vjson.widget.bind)) {
            transaction(() => {
                const scope = this.props.$context.scopeInstance

                _.forOwn(this.props.vjson.widget.bind, (widgetProperty, scopeProperty) => {
                    _.set(scope, scopeProperty, '')
                })
            })
        }
    }

    protected onValueChange(this: any, e: any) {
        // 此处不直接修改 value 值, 因为他可能是个临时的查询变量
        if (this.props.vjson.allowModify) {
            this.value = e.target.value;
        }
    }

    protected onSearch(value: any) {
        this.keepTempValue = true

        // 获取构造函数
        let inputParams: any = {}
        if (typeof this.props.vjson.widget.onOpen === 'function') {
            inputParams = this.props.vjson.widget.onOpen()

        } else if (_.isPlainObject(this.props.vjson.bind)) {
            const scope = this.props.$context.scopeInstance
            _.forOwn(this.props.vjson.bind, (widgetProperty, scopeProperty) => {
                inputParams[widgetProperty] = _.get(scope, scopeProperty)
            })
        }

        inputParams.$query = value
        inputParams.$scope = this.props.$context.scopeInstance

        // 构造并显示窗体
        const Widget = this.props.vjson.widget.content
        const widget = new Widget(inputParams)
        widget.openWidget(toJS(this.props.vjson.widget), this)

        setTimeout(() => {
            this.keepTempValue = false
        }, 600)
    }

    resetValue = _.debounce(() => {
        if (!this.keepTempValue) {
            // 还原时，看是否在400毫秒以内 触发过 keepTempValue（按钮查询） 标记
            const form = this.state.$formRef?.current;
            if (form) {
                form.setFields([
                    {
                        name: this.formItemName,
                        value: this.value
                    }
                ])
            }
        }
    }, 500)

    protected onBlur() {
        // 离开焦点时还原
        this.resetValue()
    }

    protected renderWrapper(): JSX.Element {
        if (Extend.isDebugMode()) {
            console.log('RenderSearch ', this.toString())
        }

        return (
            //@ts-ignore
            <AntdSearch key={this.key} view_id={this.key} aria-roledescription={this.view}
                        ref={this.realCtl}
                        loading={this.loading}
                        placeholder={apply(this, this.props.vjson.placeholder)}
                        maxLength={apply(this, this.props.vjson.maxLength)}
                        prefix={apply(this, this.props.vjson.prefix)}
                        size={apply(this, this.props.vjson.size)}
                        suffix={this.props.vjson.allowClear ?
                            <CloseOutlined className="anticon anticon-search ant-input-search-icon"
                                           style={{marginLeft: 0}}
                                           onClick={this.clearClick.bind(this)}
                                           title="清空"/>
                            : undefined}
                        bordered={this.props.vjson.bordered}

                        disabled={apply(this, this.props.vjson.disabled)}
                        allowClear={false}
                        onBlur={this.onBlur.bind(this)}
                        onSearch={this.onSearch.bind(this)}
                        onChange={this.onValueChange.bind(this)}
                        addonAfter={apply(this, this.props.vjson.addonAfter)}
            />
        )
    }
}
